package jvlite.ioc;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import jvlite.core.JLiteContext;
import jvlite.plugin.mybatis.MyBatisSessionMgr;

public class BeanFactory {

	private static Map<String, Object> beanMap = new HashMap<String, Object>();
	private static Map<String, Object> DIMap = new HashMap<String, Object>();
	private static Map<String, Object> ProxyMap = new HashMap<String, Object>();
	private static Map<String, Object> authMap = new HashMap<String, Object>();

	public static void loadPluginClz() {
		MyBatisSessionMgr myBatisSessionMgr = new MyBatisSessionMgr();
		beanMap.put("jvlite.plugin.mybatis.MyBatisSessionMgr",
				myBatisSessionMgr);
		JLiteContext.myBatisSessionMgr = myBatisSessionMgr;
	}

	public static void init() {
		String actionPackageName = JLiteContext.actionPackage;
		Set<Class<?>> classes = ClassHandler.getClasses(actionPackageName);
		loadPluginClz();
		for (Class<?> cc : classes) {
			// initialize the class set
			JLiteContext.clazzSet.add(cc);
			// initialize all the object for content to manage
			String clzName = cc.getName();
			String ssName = clzName.substring(clzName.lastIndexOf(".") + 1);
			if (clzName.indexOf("mvc") == -1 && clzName.indexOf("test") == -1
					&& clzName.indexOf("jdbc") == -1
					&& clzName.indexOf("router") == -1
					&& clzName.indexOf("aop") == -1
					&& clzName.indexOf("ioc") == -1
					&& clzName.indexOf("mapper") == -1) {
				// eliminate abstract class and interface
				if (ssName.startsWith("I") || ssName.startsWith("Abs")) {
					continue;
				}
				try {
					beanMap.put(clzName, cc.newInstance());
				} catch (InstantiationException e) {
					e.printStackTrace();
				} catch (IllegalAccessException e) {
					e.printStackTrace();
				}
			}
		}
	}

	public static Map<String, Object> getProxyMap() {
		return ProxyMap;
	}

	public static void setProxyMap(Map<String, Object> proxyMap) {
		ProxyMap = proxyMap;
	}

	public static Map<String, Object> getBeanMap() {
		return beanMap;
	}

	public static Map<String, Object> getDIMap() {
		return DIMap;
	}

	public static void setDIMap(Map<String, Object> dIMap) {
		DIMap = dIMap;
	}

	public static void setBeanMap(Map<String, Object> beanMap) {
		BeanFactory.beanMap = beanMap;
	}

	@SuppressWarnings("unchecked")
	public static Object getAuthBean(Map<String, Object> authMap,
			String beanName) {

		Object resultObject = null;

		List<String> hasClzAuthList = (List<String>) authMap.get("ClzAuth");
		Map<String, Object> authAndBean = (Map<String, Object>) BeanFactory.authMap
				.get(beanName);
		// only the most high authentic
		String needClzAuth = (String) authAndBean.get("ClzAuth");

		if (hasClzAuthList.contains(needClzAuth)) {
			resultObject = authAndBean.get("bean");
		} else {
			throw new RuntimeException("no enough class auth");
		}
		return resultObject;

	}

	public static Map<String, Object> getAuthMap() {
		return authMap;
	}

	public static void setAuthMap(Map<String, Object> authMap) {
		BeanFactory.authMap = authMap;
	}

	public void mkClzSet() {
		Map<String, Object> beanMap = BeanFactory.getBeanMap();
		// iterate all the classes
		for (Object object : beanMap.values()) {
			JLiteContext.clazzSet.add(object.getClass());
		}
	}

	public static Object getBeanByClz(Class<?> clz) {
		Object beanObject = null;
		if (clz != null) {
			for (Object value : beanMap.values()) {
				Class<?> clazz = value.getClass();
				if (clazz.equals(clz) || clazz.equals(clz.getSuperclass())
						|| clazz.getSuperclass().equals(clz)) {
					beanObject = value;
				}
			}
			try {
				beanObject = beanObject == null ? clz.newInstance()
						: beanObject;
			} catch (InstantiationException e) {
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				e.printStackTrace();
			}
		}
		return beanObject;
	}

}